package com.pinhuba.bams.framework.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import android.app.Activity;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.widget.ImageView;
import android.widget.TextView;
import com.pinhuba.bams.R;
import com.pinhuba.bams.framework.ConfigProperties;
import com.pinhuba.bams.framework.ErrorCode;
import com.pinhuba.bams.framework.exception.AirPlaneModeException;
import com.pinhuba.bams.framework.exception.NoInternetException;
import com.pinhuba.bams.framework.util.FileUtils;
import com.pinhuba.bams.framework.util.Loger;
import com.pinhuba.bams.framework.util.MyApplication;
import com.pinhuba.bams.framework.util.PhoneStateUtil;
import com.pinhuba.bams.framework.util.ToastHelper;

public class AsynDocDownLoadLoader extends AsyncTask<String, Integer, Integer> {
	protected Activity context;
	protected String docURL;
	protected String filePath;
	protected int position;
	protected ImageView iv;
	protected TextView progress;
	protected DocDownloadCallBackListener callback;
	protected File docFile;
	protected ErrorCode errorCode;
	protected FileUtils fileUtils;

	public AsynDocDownLoadLoader(Activity context, String FilePath, int position, ImageView iv, TextView temptv, DocDownloadCallBackListener callback) {
		this.context = context;
		this.errorCode = ErrorCode.SUCCESS;
		this.filePath = FilePath;
		this.position = position;
		this.iv = iv;
		this.progress = temptv;
		this.callback = callback;
	}

	public String getDownloadURL() {
		return this.docURL;
	}

	@Override
	protected Integer doInBackground(String... params) {
		this.docURL = params[0];
		InputStream is = null;
		OutputStream os = null;
		HttpURLConnection conn = null;
		int progress = 0;
		Loger.d("The download in :" + this.docURL);

		try {
			PhoneStateUtil.checkNetWork(context);
		} catch (AirPlaneModeException e) {
			e.printStackTrace();
			errorCode = ErrorCode.AIRPLANE_MODE;
		} catch (NoInternetException e) {
			e.printStackTrace();
			errorCode = ErrorCode.NO_INTERNET;
		}
		if (errorCode != ErrorCode.SUCCESS) {
			return 0;
		}

		if (!fileUtils.isSDExist()) {
			errorCode = ErrorCode.NOSDCARD;
			return 0;
		}

		File file = new File(filePath);
		Loger.d("The filePaht is:" + filePath);
		if (file.exists()) {
			errorCode = ErrorCode.FILE_EXIST;
			return -1;
		}

		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdir();
		}
		try {
//			Loger.d("The URL is:" + URLEncoder.encode(this.docURL, "utf-8"));
//			String str = URLEncoder.encode(this.docURL, "utf-8");
//			str = str.replaceAll("\\+", "%20");
//			str = str.replaceAll("%3A", ":").replaceAll("%2F", "/");
//			Loger.d("The URL is:" + str);
//			URL url = new URL(str);

			URL url = new URL(this.docURL);
			
			conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setRequestMethod("GET");
			conn.connect();
			conn.setConnectTimeout(ConfigProperties.TIMEOUT);
			int contentlength = conn.getContentLength();
			Loger.d("The length is :" + contentlength);
			if (contentlength <= 0) {
				if (conn != null) {
					conn.disconnect();
				}
				errorCode = ErrorCode.INVALID_REQUEST;
				return 0;
			}

			is = conn.getInputStream();
			int hasRead = 0;
			byte[] bs = new byte[1024 * 16];
			int len;
			os = new FileOutputStream(file);
			// 开始读取
			int progressBefore = 0;
			publishProgress(progress);
			while ((len = is.read(bs)) != -1) {
				os.write(bs, 0, len);
				hasRead += len;
				Loger.d("The num is:" + hasRead);
				progress = (int) ((double) hasRead / (double) contentlength * 100);
				if (hasRead > progressBefore) {
					progressBefore = hasRead;
					publishProgress(progress);
				}
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
			errorCode = ErrorCode.INVALID_REQUEST;
		} catch (IOException e) {
			e.printStackTrace();
			errorCode = ErrorCode.INVALID_IO;
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					errorCode = ErrorCode.INVALID_IO;
				}
			}
			if (os != null) {
				try {
					os.flush();
					os.close();
				} catch (IOException e) {
					errorCode = ErrorCode.INVALID_IO;
				}
			}

			if (conn != null) {
				conn.disconnect();
			}
		}

		if (errorCode == ErrorCode.SUCCESS) {
			if (progress == 100) {
				return 1;
			} else {
				errorCode = ErrorCode.UNKNOWN_EXCEPTION;
				if (file.exists()) {
					if (!file.delete()) {
						errorCode = ErrorCode.INVALID_IO;
					}
				}
				return 0;
			}
		} else {
			return 0;
		}
	}

	@Override
	protected void onPreExecute() {
		fileUtils = new FileUtils();
		super.onPreExecute();
	}

	@Override
	protected void onPostExecute(Integer result) {

		if (result == 0) {// 等于0表示发生异常
			// 根据ErrorCode类型打印error名字
			String errorName = null;
			// 不能直接使用getResources()
			Resources rs = MyApplication.getAppContext().getResources();
			switch (errorCode) {
			case UNKNOWN_EXCEPTION:// 未知异常
				errorName = rs.getString(R.string.unknown_exception_happen);
				break;
			case NO_INTERNET:// 没有接入网络
				errorName = rs.getString(R.string.exception_no_internet);
				break;
			case AIRPLANE_MODE:// 处在飞行模式
				errorName = rs.getString(R.string.exception_airplane_mode);
				break;
			case NOSDCARD:// 没有检测到sd卡
				errorName = rs.getString(R.string.exception_nosdcard);
				break;
			case FILE_EXIST:// 文件已经存在
				errorName = rs.getString(R.string.same_dir_name);
				break;
			case INVALID_REQUEST:// 非法的请求
				errorName = rs.getString(R.string.exception_invaild_request);
				break;
			case INVALID_IO:// 非法的IO操作
				errorName = rs.getString(R.string.exception_invaild_io);
				break;

			default:
				break;
			}
			ToastHelper.showShortMsg(errorName);// 输出错误信息
		}

		this.callback.docCallBack(position, result, iv, progress, this.errorCode);
		DocDownloadLoadManager.removeTask(AsynDocDownLoadLoader.this);
		super.onPostExecute(result);
	}

	@Override
	protected void onCancelled() {
		DocDownloadLoadManager.removeTask(AsynDocDownLoadLoader.this);
		super.onCancelled();
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		if (values[0] == 0) {
			this.iv.setImageResource(R.drawable.download_process);
		} else if (values[0] == 100) {
			this.iv.setImageResource(R.drawable.download_finish);
		}

		this.progress.setText(values[0] + "%");
		super.onProgressUpdate(values);
	}
}
